import EvaluationSelect, {
  Value as EvaluationSelectValue,
} from '@/components/EvaluationSelect';
import FileUpload from '@/components/FileUpload';
import { audioSynthesisV1ControllerEarbuds2Earbuds } from '@/services/auto/audioSynthesis';
import { ModalForm, ProForm, ProFormList } from '@ant-design/pro-components';
import { css } from '@emotion/css';
import { useRequest } from 'ahooks';
import { Alert, Checkbox, Form, message, Radio } from 'antd';
import {
  EvaluationCategory,
  FileGroup,
  simulationAlgoType,
} from 'common/utils/data';
import { PropsWithChildren } from 'react';

interface FormData
  extends Omit<
    API.Earbuds2EarbudsDto,
    | 'currentEvaluationUuid'
    | 'currentDataGroup'
    | 'targets'
  > {
  current: EvaluationSelectValue<true>;
  targets: {data: EvaluationSelectValue<true>;id: string;}[];
  presetFiles?: string[];
}

interface Props {
  reload?: () => void;
}

export default (props: PropsWithChildren<Props>) => {
  const { reload, children } = props;

  const [form] = Form.useForm<FormData>();

  const current = Form.useWatch('current', form);

  const { runAsync } = useRequest(audioSynthesisV1ControllerEarbuds2Earbuds, {
    manual: true,
  });

  return (
    <ModalForm
      layout="horizontal"
      width={800}
      labelCol={{ style: { width: 100 } }}
      modalProps={{
        maskClosable: false,
      }}
      form={form}
      onOpenChange={(val) => {
        if (val) {
        } else {
          form.resetFields();
        }
      }}
      title="添加云试听任务"
      trigger={children as JSX.Element}
      onFinish={(values) => {
        const { current, targets, files, presetFiles, ...restValues } = values;
        return runAsync({
          currentEvaluationUuid: current.evaluationUuid!,
          currentDataGroup: current.dataGroup!,
          targets: targets.map(target => ({
            evaluationUuid: target.data.evaluationUuid!,
            dataGroup: target.data.dataGroup!,
          })),
          files: [...(files ?? []), ...(presetFiles ?? [])],
          ...restValues,
        })
          .then(() => {
            message.success('操作成功');
            reload?.();
            return true;
          })
          .catch(() => {
            return false;
          });
      }}
    >
      <ProForm.Item
        name="current"
        label="当前耳机"
        required
        rules={[
          {
            validator: (_, value) => {
              return EvaluationSelect.getValidator(value, true, true);
            },
          },
        ]}
        extra={
          current ? (
            <Alert
              className="mt-[8px]"
              showIcon
              type="warning"
              message="请确保您的耳机配置与图片中一致"
            />
          ) : undefined
        }
      >
        <EvaluationSelect category={EvaluationCategory.EARBUDS} withDataGroup />
      </ProForm.Item>
      <ProForm.Item required label="当前音频" className="mb-0">
        <ProForm.Item
          name="files"
          rules={[
            (form) => {
              const presetFiles = form.getFieldValue('presetFiles');
              return {
                required: !presetFiles?.length,
                message: '请上传音频或选择预设音频',
                type: 'array',
              };
            },
          ]}
        >
          <FileUpload
            audioDurationLimit
            max={10}
            size={100}
            fileGroup={FileGroup.TEMP_AUDIO_SYNTHESIS}
            ext={[
              '.flac',
              '.wav',
              '.aiff',
              '.mp3',
              '.aifc',
              '.au',
              '.avr',
              '.caf',
              '.htk',
              '.iff',
              '.mat',
              '.mpc',
              '.ogg',
              '.paf',
              '.pcm',
              '.pvf',
              '.rf64',
              '.sd2',
              '.sds',
              '.sf',
              '.voc',
              '.vox',
              '.w64',
              '.wve',
              '.x',
            ]}
          />
        </ProForm.Item>
        <ProForm.Item
          name="presetFiles"
          label="预设音乐"
          extra="开源音乐来自：pixabay.com"
        >
          <Checkbox.Group
            options={[
              {
                value: `${FileGroup.AUDIO_SYNTHESIS}/测试音乐1-流行音乐片段（较多低频）20241210.wav`,
                label: '测试音乐1-流行音乐片段（较多低频）.wav',
              },
              {
                value: `${FileGroup.AUDIO_SYNTHESIS}/测试音乐2-轻快的电影配乐.wav`,
                label: '测试音乐2-轻快的电影配乐.wav',
              },
            ]}
          />
        </ProForm.Item>
      </ProForm.Item>
      <ProFormList
        copyIconProps={false}
        label="目标耳机"
        name="targets"
        required
        max={10}
        min={1}
        initialValue={[
          {
            id: `key-${Math.random().toString()}`,
            data: undefined,
          },
        ]}
        creatorButtonProps={{
          position: 'bottom',
          creatorButtonText: '新增目标耳机',
        }}
        creatorRecord={() => {
          return {
            id: `key-${Math.random().toString()}`,
            data: undefined,
          }
        }}
        className={css({
          '& .ant-pro-form-list-item': {
            alignItems: 'flex-start !important'
          },
        })}
        rules={[
          {
            validator: (_, val: FormData['targets']) => {
              for (let i = 0; i < val.length; i++) {
                const res = val.filter(item => item.data?.evaluationUuid === val[i].data?.evaluationUuid && item.data?.dataGroup === val[i].data?.dataGroup);
                if (res.length > 1) {
                  return Promise.reject(
                    new Error(`第${i + 1}项目标耳机有重复`),
                  );
                }
              }
              return Promise.resolve();
            },
          },
        ]}
      >
        <ProForm.Item name="data" rules={[
          {
            validator: (_, value) => {
              return EvaluationSelect.getValidator(value, true, true);
            },
          },
        ]}>
          <EvaluationSelect category={EvaluationCategory.EARBUDS} withDataGroup />
        </ProForm.Item>
      </ProFormList>
      <ProForm.Item
        label="模拟算法"
        name="simulationAlgo"
        rules={[{ required: true, message: '请选择模拟算法' }]}
      >
        <Radio.Group options={simulationAlgoType.$listSelect} />
      </ProForm.Item>
    </ModalForm>
  );
};
